package com.anc.platform.utils;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.function.Function;

public class TreeBuilder {

    /**
     * 构建树形结构
     *
     * @param treeNodes      传入的树节点列表
     * @param rootParentCode 根节点编号
     * @return
     */
    public static <T extends AbstractTreeNode<T>> List<T> bulidTrees(List<T> treeNodes, String rootParentCode) {
        return bulidSortTrees(treeNodes, rootParentCode, null);
    }

    /**
     * 构建树形结构并排序
     *
     * @param treeNodes      传入的树节点列表
     * @param rootParentCode 根节点编号
     * @param com            排序函数
     * @return
     */
    public static <T extends AbstractTreeNode<T>> List<T> bulidSortTrees(List<T> treeNodes, String rootParentCode, Comparator<T> com) {
        return bulidSortCallBackTrees(treeNodes, rootParentCode, com, null);
    }

    /**
     * 构建树行结构并对节点进行回调(对节点对象进行处理)
     *
     * @param treeNodes      传入的树节点列表
     * @param rootParentCode 根节点编号
     * @param callBack       对象处理函数
     * @return
     */
    public static <T extends AbstractTreeNode<T>> List<T> bulidCallBackTrees(List<T> treeNodes, String rootParentCode, Function<T,T> callBack) {
        return bulidSortCallBackTrees(treeNodes, rootParentCode, null, callBack);
    }

    /**
     * 使用递归方法建树(并排序)
     *
     * @param rootParentCode 根节点父级编号
     * @param treeNodes
     * @return
     */
    public static <T extends AbstractTreeNode<T>> List<T> bulidSortCallBackTrees(List<T> treeNodes, String rootParentCode, Comparator<T> com, Function<T,T> callBack) {
        String root = "0";
        if (StringUtils.isNotEmpty(rootParentCode)) {
            root = rootParentCode;
        }
        List<T> trees = new ArrayList<>();
        for (T treeNode : treeNodes) {
            if (root.equals(treeNode.getParentCode())) {
                // 回调函数可能把本节点置为null
                treeNode = findChildren(treeNode, treeNodes, com, callBack);
                if (treeNode != null) {
                    trees.add(treeNode);
                }
            }
        }
        if (com != null) {
            trees.sort(com);
        }
        return trees;
    }

    /**
     * 递归查找子节点
     *
     * @param treeNodes
     * @return
     */
    public static <T extends AbstractTreeNode<T>> T findChildren(T treeNode, List<T> treeNodes, Comparator<T> com, Function<T,T> callBack) {
        for (T it : treeNodes) {
            if (treeNode.getCode().equals(it.getParentCode())) {
                if (treeNode.getChildren() == null) {
                    treeNode.setChildren(new ArrayList<>());
                }
                // 回调函数可能把本节点置为null
                it = findChildren(it, treeNodes, com, callBack);
                if (it != null) {
                    treeNode.getChildren().add(it);
                }
            }
        }
        // 对子节点进行排序
        if (com != null && CollectionUtils.isNotEmpty(treeNode.getChildren())) {
            treeNode.getChildren().sort(com);
        }
        // 对当前节点进行完塞入子节点后进行回调(例如统计它下边的子节点的个数/子节点的商品个数,并塞入自己对象中)
        // 返回原对象可能为null
        if (callBack != null) {
            treeNode = callBack.apply(treeNode);
        }
        return treeNode;
    }
}
